<?php
require '_config.php';
require 'twilio-php/Services/Twilio.php';


function read_json($path) {
    if (!file_exists($path)) {
        return NULL;
    }
    if (strpos($path, '..') !== false || strpos(ltrim($path), '/') === 0) {
        die('Permission denied');
    }
    return json_decode(file_get_contents($path), TRUE);
}

function write_json($path, $obj) {
    file_put_contents($path, json_encode($obj), LOCK_EX);
}

function num2name($num) {
    $names = read_json('data/_names');
    if (array_key_exists($num, $names))
        return $names[$num];
    return NULL;
}

function get_subscribers($num) {
    $subs = read_json("data/$num");
    if ($subs === NULL)
        return array();
    return array_keys($subs);
}

function add_name($num, $name) {
    $names = read_json('data/_names');
    $names[$num] = $name;
    write_json('data/_names', $names);
}

function add_subscriber($num, $sub_num) {
    $list = read_json("data/$num");
    if ($list === NULL)
        $list = array();

    if (array_key_exists($sub_num, $list))
        return;
    $list[$sub_num] = array();
    write_json("data/$num", $list);
}

function remove_subscriber($num, $sub_num) {
    if (strpos($num, '..') !== false || strpos($num, '/') !== false)
        die('Malformed number');

    $list = get_subscribers($num);
    if (!array_key_exists($sub_num, $list))
        return;
    unset($list[$sub_num]);
    write_json("data/$num", $list);
}

function short_name($name) {
    $name_parts = explode(' ', $name);
    if (count($name_parts) == 1 || strlen($name_parts[1]) == 0)
        return $name_parts[0];
    else
        return $name_parts[0] . strtoupper(substr($name_parts[1], 0, 1));
}




function cmd_join($name) {
    global $req, $resp, $users;
    
    if ($name)
        add_name($req['From'], $name);
    add_subscriber($req['To'], $req['From']);
    if (num2name($req['From']))
    {
        $resp->sms("You are now subscribed! Text #leave at any time to unsubscribe.");
    }
    else
    {
        $resp->sms("You are now subscribed! Reply with \"#join [your name]\" if you want your messages to show your name. Text #leave at any time to unsubscribe.");
    }
}

function cmd_add($info) {
    global $req, $resp, $users;

    $parts = explode(' ', $info, 2);

    if (count($parts) < 2) {
        $resp->sms("That didn't work. Try \"#add [number] [names]\"");
        return;
    }

    $num = trim($parts[0]);
    $name = trim($parts[1]);
    
    if (!preg_match("/^(\\+1)?(\\d{10})$/", $num, $matches)) {
        $resp->sms("That didn't work. Try \"#add [number] [names]\"");
        return;
    }
    
    if ($matches[1] != "+1") {
        $num = "+1" . $num;
    }

    add_name($num, $name);
    add_subscriber($req['To'], $num);
    $resp->sms("$num is now subscribed as $name.");
}

function cmd_confirm($dummy) {
    global $req, $resp, $users;
}

function cmd_leave($dummy) {
    global $req, $resp, $users;
    
    remove_subscriber($req['To'], $req['From']);
    $resp->sms("You have unsubscribed from this number.");
}

function cmd_help($dummy) {
    global $req, $resp, $users;
}

function cmd_send($dummy) {
    global $req, $resp, $users;
    
    $list_members = get_subscribers($req['To']);
    if (!$list_members) {
        $resp->sms('[No recipients found!]');
        return;
    }

    $from = $req['From'];
    $fromUser = num2name($from);
    if ($fromUser)
        $from = short_name($fromUser);

    $msg = $from . ': ' . $req['Body'];
    
    foreach ($list_members as $number) {
        $resp->sms($msg, array('to' => $number));
    }
}




$php_ver = explode('.', PHP_VERSION);
if ($php_ver[0] < 5)
    die('PHP 5 is required');

$req = array_merge($_GET, $_POST);

#$validator = new Services_Twilio_RequestValidator(TWILIO_TOKEN);
#$url = $_SERVER["SCRIPT_URI"];
#$signature = $_SERVER["X-Twilio-Signature"];
#if (!$validator->validate($signature, $url, $req)) { die("Invalid signature $signature"); }

if ($req['AccountSid'] !== TWILIO_SID) { die("Invalid request"); }

$body = $req['Body'];
$to = $req['To'];

$cmd = '';
$arg = '';

if (preg_match("/^#(join|add|confirm|leave|help)\\s*(.*)$/i",
        $body, $results)) {
    $cmd = strtolower($results[1]);
    $arg = $results[2];
}
else {
    $cmd = 'send';
    $arg = $body;
}

$resp = new Services_Twilio_Twiml();

call_user_func("cmd_$cmd", $arg);

header('Content-Type: text/xml');
print $resp;
?>